package ar.com.fiuba.service.impl;

import java.util.Map;

import ar.com.fiuba.SystemKeys;
import ar.com.fiuba.application.api.CoefficientCalculationStrategySelector;
import ar.com.fiuba.domain.CoefficientCalculationStrategy;
import ar.com.fiuba.domain.Word;
import ar.com.fiuba.domain.api.Dictionary;
import ar.com.fiuba.domain.api.WordFactory;
import ar.com.fiuba.domain.exceptions.DomainException;
import ar.com.fiuba.domain.impl.Corrector;
import ar.com.fiuba.service.api.Service;

public class CorrectionService implements Service {

	private CoefficientCalculationStrategySelector coefficientCalculationStrategySelector;

	private Dictionary dictionary;

	private WordFactory wordFactory;

	public CorrectionService(CoefficientCalculationStrategySelector coefficientCalculationStrategySelector,
			Dictionary dictionary, WordFactory wordFactory) {
		this.coefficientCalculationStrategySelector = coefficientCalculationStrategySelector;
		this.dictionary = dictionary;
		this.wordFactory = wordFactory;
	}

	public void run(Map<String, String> parameters) {
		long then = System.currentTimeMillis();
		String coefficientAlgorythm = parameters.get(SystemKeys.COEFFICIENT_ALGORYTHM);
		String inputWord = parameters.get(SystemKeys.INPUT_WORD);

		CoefficientCalculationStrategy coefficientCalculationStrategy = resolveStrategy(coefficientAlgorythm);
		Corrector corrector = new Corrector(dictionary, coefficientCalculationStrategy);
		Word wordToCorrect;
		try {
			wordToCorrect = wordFactory.makeWord(inputWord);
		} catch (DomainException e) {
			// Assuming valid length of word/n-gramm.
			e.printStackTrace();
			return;
		}
		Word correctedWord = corrector.getBestMatch(wordToCorrect);
		long now = System.currentTimeMillis();
		System.out.println("Palabra '" + wordToCorrect.getValue() + "' corregida como '" + correctedWord.getValue()
				+ "' en " + ((now - then) / 1000.00) + " segundos.");
	}

	private CoefficientCalculationStrategy resolveStrategy(String coefficientAlgorythm) {
		return coefficientCalculationStrategySelector.resolveCoefficientCalculationStrategy(coefficientAlgorythm);
	}
}
